<?php

namespace App\Console\Commands\Tools\Camera;

use App\Kuafu\Shop\Model\ShopMonitorDataHourModel;
use App\Kuafu\Shop\Model\ShopMonitorDataModel;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;

class CleanShopMonitorData extends Command
{
    protected $signature   = 'tools:clean-shop-monitor-data {--cycle=hourly}';
    protected $description = '按小时纬度清理 kf_shop_monitor_data_hour 表数据';

    public function handle()
    {
        $this->dealLastHour();
    }

    private function dealLastHour()
    {
        ini_set('memory_limit', '2048M');
        // 周月推送
        $cycleType = $this->option('cycle');
        switch ($cycleType) {
            case 'yesterday':
                $startTimestamp = Carbon::now()->subDay()->startOfDay()->getTimestamp();
                $endTimestamp   = Carbon::now()->subDay()->endOfDay()->getTimestamp();
                break;
            case 'customer':
                $startTimestamp = Carbon::now()->subDays(1)->startOfDay()->getTimestamp();
                $endTimestamp   = Carbon::now()->subDays(1)->endOfDay()->getTimestamp();
                break;
            default:
                $startTimestamp = Carbon::now()->subHour()->startOfHour()->getTimestamp();
                $endTimestamp   = Carbon::now()->subHour()->endOfHour()->getTimestamp();
                break;
        }

        $formatDatum = [];
        ShopMonitorDataModel::query()
                            ->whereIn('type', [
                                ShopMonitorDataModel::TYPE_IN_SHOP,
                                ShopMonitorDataModel::TYPE_OUT_SHOP,
                                ShopMonitorDataModel::TYPE_PASS_SHOP,
                            ])
                            ->where('dataAt', '>=', $startTimestamp)
                            ->where('dataAt', '<=', $endTimestamp)
                            ->chunkById(10000, function ($dataItems) use (&$formatDatum) {
                                $formatDatum = $this->getFormatDatum($dataItems, $formatDatum);
                            });

        ShopMonitorDataHourModel::query()
                                ->where('dataAt', '>=', $startTimestamp)
                                ->where('dataAt', '<=', $endTimestamp)
                                ->delete();

        collect($formatDatum)->chunk(1000)->each(function (Collection $formatDatumPluck) {
            ShopMonitorDataHourModel::query()->insert($formatDatumPluck->values()->toArray());
        });
    }

    private function dealYesterday()
    {
        $this->info('处理昨日数据');
        ini_set('memory_limit', '2048M');
        $startTimestamp = Carbon::yesterday()->startOfDay()->getTimestamp();
        $endTimestamp   = Carbon::yesterday()->endOfDay()->getTimestamp();

        $formatDatum = [];
        ShopMonitorDataModel::query()
                            ->whereIn('type', [
                                ShopMonitorDataModel::TYPE_IN_SHOP,
                                ShopMonitorDataModel::TYPE_OUT_SHOP,
                                ShopMonitorDataModel::TYPE_PASS_SHOP,
                            ])
                            ->where('dataAt', '>=', $startTimestamp)
                            ->where('dataAt', '<=', $endTimestamp)
                            ->chunkById(100000, function ($dataItems) use (&$formatDatum) {
                                $formatDatum = $this->getFormatDatum($dataItems, $formatDatum);
                            });

        ShopMonitorDataHourModel::query()
                                ->where('dataAt', '>=', $startTimestamp)
                                ->where('dataAt', '<=', $endTimestamp)
                                ->delete();

        collect($formatDatum)->chunk(5000)->each(function (Collection $formatDatumPluck) {
            ShopMonitorDataHourModel::query()->insert($formatDatumPluck->values()->toArray());
        });
    }

    private function dealHistory()
    {
        ini_set('memory_limit', '4048M');

        $startAt = Carbon::now()->startOfDay();

        ShopMonitorDataModel::query()
                            ->whereIn('type', [
                                ShopMonitorDataModel::TYPE_IN_SHOP,
                                ShopMonitorDataModel::TYPE_OUT_SHOP,
                                ShopMonitorDataModel::TYPE_PASS_SHOP,
                            ])

//                            ->where('dataAt', '>=', $startAt)
                            ->chunkById(100000, function ($dataItems) {
                $this->info('latest id: ' . $dataItems->first()['id']);

                // 先查出该门店的某个时间内的数据
                $formatDatum = [];
                $formatDatum = $this->getFormatDatum($dataItems, $formatDatum);

                ShopMonitorDataHourModel::query()->insert($formatDatum);

            });
    }

    /**
     * @param $dataItems
     * @param array $formatDatum
     * @return array
     */
    private function getFormatDatum($dataItems, array $formatDatum): array
    {
        $dataItems->each(function ($item) use (&$formatDatum) {
            $formatDataAt  = strtotime(date('Y-m-d H:00:00', $item['dataAt']));
            $formatDataKey = vsprintf('%s_%s_%s_%s', [
                $item['shopId'],
                $item['type'],
                $item['monitorId'],
                $formatDataAt
            ]);

            if (empty($formatDatum[$formatDataKey])) {
                $formatDatum[$formatDataKey] = [
                    'shopId'       => $item['shopId'],
                    'monitorId'    => $item['monitorId'],
                    'dataAt'       => $formatDataAt,
                    'count'        => $item['count'],
                    'temperature'  => 0,
                    'createdAt'    => time(),
                    'updatedAt'    => time(),
                    'createdByUid' => 0,
                    'updatedByUid' => 0,
                    'type'         => $item['type']
                ];
            } else {
                $formatDatum[$formatDataKey]['count'] += $item['count'];
            }
        });
        return $formatDatum;
    }
}
